//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2021 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto/tree/main/CodeGenerator. DO NOT EDIT.

import Foundation
import SotoCore

extension EMRContainers {
    // MARK: Enums

    public enum ContainerProviderType: String, CustomStringConvertible, Codable {
        case eks = "EKS"
        public var description: String { return self.rawValue }
    }

    public enum EndpointState: String, CustomStringConvertible, Codable {
        case active = "ACTIVE"
        case creating = "CREATING"
        case terminated = "TERMINATED"
        case terminatedWithErrors = "TERMINATED_WITH_ERRORS"
        case terminating = "TERMINATING"
        public var description: String { return self.rawValue }
    }

    public enum FailureReason: String, CustomStringConvertible, Codable {
        case clusterUnavailable = "CLUSTER_UNAVAILABLE"
        case internalError = "INTERNAL_ERROR"
        case userError = "USER_ERROR"
        case validationError = "VALIDATION_ERROR"
        public var description: String { return self.rawValue }
    }

    public enum JobRunState: String, CustomStringConvertible, Codable {
        case cancelPending = "CANCEL_PENDING"
        case cancelled = "CANCELLED"
        case completed = "COMPLETED"
        case failed = "FAILED"
        case pending = "PENDING"
        case running = "RUNNING"
        case submitted = "SUBMITTED"
        public var description: String { return self.rawValue }
    }

    public enum PersistentAppUI: String, CustomStringConvertible, Codable {
        case disabled = "DISABLED"
        case enabled = "ENABLED"
        public var description: String { return self.rawValue }
    }

    public enum VirtualClusterState: String, CustomStringConvertible, Codable {
        case arrested = "ARRESTED"
        case running = "RUNNING"
        case terminated = "TERMINATED"
        case terminating = "TERMINATING"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct CancelJobRunRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "id", location: .uri(locationName: "jobRunId")),
            AWSMemberEncoding(label: "virtualClusterId", location: .uri(locationName: "virtualClusterId"))
        ]

        /// The ID of the job run to cancel.
        public let id: String
        /// The ID of the virtual cluster for which the job run will be canceled.
        public let virtualClusterId: String

        public init(id: String, virtualClusterId: String) {
            self.id = id
            self.virtualClusterId = virtualClusterId
        }

        public func validate(name: String) throws {
            try self.validate(self.id, name: "id", parent: name, max: 64)
            try self.validate(self.id, name: "id", parent: name, min: 1)
            try self.validate(self.id, name: "id", parent: name, pattern: "[0-9a-z]+")
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, max: 64)
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, min: 1)
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, pattern: "[0-9a-z]+")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct CancelJobRunResponse: AWSDecodableShape {
        /// The output contains the ID of the cancelled job run.
        public let id: String?
        /// The output contains the virtual cluster ID for which the job run is cancelled.
        public let virtualClusterId: String?

        public init(id: String? = nil, virtualClusterId: String? = nil) {
            self.id = id
            self.virtualClusterId = virtualClusterId
        }

        private enum CodingKeys: String, CodingKey {
            case id
            case virtualClusterId
        }
    }

    public struct CloudWatchMonitoringConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// The name of the log group for log publishing.
        public let logGroupName: String
        /// The specified name prefix for log streams.
        public let logStreamNamePrefix: String?

        public init(logGroupName: String, logStreamNamePrefix: String? = nil) {
            self.logGroupName = logGroupName
            self.logStreamNamePrefix = logStreamNamePrefix
        }

        public func validate(name: String) throws {
            try self.validate(self.logGroupName, name: "logGroupName", parent: name, max: 512)
            try self.validate(self.logGroupName, name: "logGroupName", parent: name, min: 1)
            try self.validate(self.logGroupName, name: "logGroupName", parent: name, pattern: "[\\.\\-_/#A-Za-z0-9]+")
            try self.validate(self.logStreamNamePrefix, name: "logStreamNamePrefix", parent: name, max: 256)
            try self.validate(self.logStreamNamePrefix, name: "logStreamNamePrefix", parent: name, min: 1)
            try self.validate(self.logStreamNamePrefix, name: "logStreamNamePrefix", parent: name, pattern: ".*\\S.*")
        }

        private enum CodingKeys: String, CodingKey {
            case logGroupName
            case logStreamNamePrefix
        }
    }

    public class Configuration: AWSEncodableShape & AWSDecodableShape {
        /// The classification within a configuration.
        public let classification: String
        /// A list of additional configurations to apply within a configuration object.
        public let configurations: [Configuration]?
        /// A set of properties specified within a configuration classification.
        public let properties: [String: String]?

        public init(classification: String, configurations: [Configuration]? = nil, properties: [String: String]? = nil) {
            self.classification = classification
            self.configurations = configurations
            self.properties = properties
        }

        public func validate(name: String) throws {
            try self.validate(self.classification, name: "classification", parent: name, max: 1024)
            try self.validate(self.classification, name: "classification", parent: name, min: 1)
            try self.validate(self.classification, name: "classification", parent: name, pattern: ".*\\S.*")
            try self.configurations?.forEach {
                try $0.validate(name: "\(name).configurations[]")
            }
            try self.validate(self.configurations, name: "configurations", parent: name, max: 100)
            try self.properties?.forEach {
                try validate($0.key, name: "properties.key", parent: name, max: 1024)
                try validate($0.key, name: "properties.key", parent: name, min: 1)
                try validate($0.key, name: "properties.key", parent: name, pattern: ".*\\S.*")
                try validate($0.value, name: "properties[\"\($0.key)\"]", parent: name, max: 1024)
                try validate($0.value, name: "properties[\"\($0.key)\"]", parent: name, min: 1)
                try validate($0.value, name: "properties[\"\($0.key)\"]", parent: name, pattern: ".*\\S.*")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case classification
            case configurations
            case properties
        }
    }

    public struct ConfigurationOverrides: AWSEncodableShape & AWSDecodableShape {
        /// The configurations for the application running by the job run.
        public let applicationConfiguration: [Configuration]?
        /// The configurations for monitoring.
        public let monitoringConfiguration: MonitoringConfiguration?

        public init(applicationConfiguration: [Configuration]? = nil, monitoringConfiguration: MonitoringConfiguration? = nil) {
            self.applicationConfiguration = applicationConfiguration
            self.monitoringConfiguration = monitoringConfiguration
        }

        public func validate(name: String) throws {
            try self.applicationConfiguration?.forEach {
                try $0.validate(name: "\(name).applicationConfiguration[]")
            }
            try self.validate(self.applicationConfiguration, name: "applicationConfiguration", parent: name, max: 100)
            try self.monitoringConfiguration?.validate(name: "\(name).monitoringConfiguration")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationConfiguration
            case monitoringConfiguration
        }
    }

    public struct ContainerInfo: AWSEncodableShape & AWSDecodableShape {
        /// The information about the EKS cluster.
        public let eksInfo: EksInfo?

        public init(eksInfo: EksInfo? = nil) {
            self.eksInfo = eksInfo
        }

        public func validate(name: String) throws {
            try self.eksInfo?.validate(name: "\(name).eksInfo")
        }

        private enum CodingKeys: String, CodingKey {
            case eksInfo
        }
    }

    public struct ContainerProvider: AWSEncodableShape & AWSDecodableShape {
        /// The ID of the container cluster.
        public let id: String
        /// The information about the container cluster.
        public let info: ContainerInfo?
        /// The type of the container provider. EKS is the only supported type as of now.
        public let type: ContainerProviderType

        public init(id: String, info: ContainerInfo? = nil, type: ContainerProviderType) {
            self.id = id
            self.info = info
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.id, name: "id", parent: name, max: 256)
            try self.validate(self.id, name: "id", parent: name, min: 1)
            try self.validate(self.id, name: "id", parent: name, pattern: ".*\\S.*")
            try self.info?.validate(name: "\(name).info")
        }

        private enum CodingKeys: String, CodingKey {
            case id
            case info
            case type
        }
    }

    public struct CreateManagedEndpointRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "virtualClusterId", location: .uri(locationName: "virtualClusterId"))
        ]

        /// The certificate ARN of the managed endpoint.
        public let certificateArn: String
        /// The client idempotency token for this create call.
        public let clientToken: String
        /// The configuration settings that will be used to override existing configurations.
        public let configurationOverrides: ConfigurationOverrides?
        /// The ARN of the execution role.
        public let executionRoleArn: String
        /// The name of the managed endpoint.
        public let name: String
        /// The Amazon EMR release version.
        public let releaseLabel: String
        /// The tags of the managed endpoint.
        public let tags: [String: String]?
        /// The type of the managed endpoint.
        public let type: String
        /// The ID of the virtual cluster for which a managed endpoint is created.
        public let virtualClusterId: String

        public init(certificateArn: String, clientToken: String = CreateManagedEndpointRequest.idempotencyToken(), configurationOverrides: ConfigurationOverrides? = nil, executionRoleArn: String, name: String, releaseLabel: String, tags: [String: String]? = nil, type: String, virtualClusterId: String) {
            self.certificateArn = certificateArn
            self.clientToken = clientToken
            self.configurationOverrides = configurationOverrides
            self.executionRoleArn = executionRoleArn
            self.name = name
            self.releaseLabel = releaseLabel
            self.tags = tags
            self.type = type
            self.virtualClusterId = virtualClusterId
        }

        public func validate(name: String) throws {
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, max: 2048)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, min: 44)
            try self.validate(self.certificateArn, name: "certificateArn", parent: name, pattern: "^arn:(aws[a-zA-Z0-9-]*):acm:.+:(\\d{12}):certificate/.+$")
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 64)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: ".*\\S.*")
            try self.configurationOverrides?.validate(name: "\(name).configurationOverrides")
            try self.validate(self.executionRoleArn, name: "executionRoleArn", parent: name, max: 2048)
            try self.validate(self.executionRoleArn, name: "executionRoleArn", parent: name, min: 20)
            try self.validate(self.executionRoleArn, name: "executionRoleArn", parent: name, pattern: "^arn:(aws[a-zA-Z0-9-]*):iam::(\\d{12})?:(role((\\u002F)|(\\u002F[\\u0021-\\u007F]+\\u002F))[\\w+=,.@-]+)$")
            try self.validate(self.name, name: "name", parent: name, max: 64)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "[\\.\\-_/#A-Za-z0-9]+")
            try self.validate(self.releaseLabel, name: "releaseLabel", parent: name, max: 64)
            try self.validate(self.releaseLabel, name: "releaseLabel", parent: name, min: 1)
            try self.validate(self.releaseLabel, name: "releaseLabel", parent: name, pattern: "[\\.\\-_/A-Za-z0-9]+")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: ".*\\S.*")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, min: 0)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, pattern: ".*\\S.*")
            }
            try self.validate(self.type, name: "type", parent: name, max: 64)
            try self.validate(self.type, name: "type", parent: name, min: 1)
            try self.validate(self.type, name: "type", parent: name, pattern: ".*\\S.*")
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, max: 64)
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, min: 1)
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, pattern: "[0-9a-z]+")
        }

        private enum CodingKeys: String, CodingKey {
            case certificateArn
            case clientToken
            case configurationOverrides
            case executionRoleArn
            case name
            case releaseLabel
            case tags
            case type
        }
    }

    public struct CreateManagedEndpointResponse: AWSDecodableShape {
        /// The output contains the ARN of the managed endpoint.
        public let arn: String?
        /// The output contains the ID of the managed endpoint.
        public let id: String?
        /// The output contains the name of the managed endpoint.
        public let name: String?
        /// The output contains the ID of the virtual cluster.
        public let virtualClusterId: String?

        public init(arn: String? = nil, id: String? = nil, name: String? = nil, virtualClusterId: String? = nil) {
            self.arn = arn
            self.id = id
            self.name = name
            self.virtualClusterId = virtualClusterId
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case id
            case name
            case virtualClusterId
        }
    }

    public struct CreateVirtualClusterRequest: AWSEncodableShape {
        /// The client token of the virtual cluster.
        public let clientToken: String
        /// The container provider of the virtual cluster.
        public let containerProvider: ContainerProvider
        /// The specified name of the virtual cluster.
        public let name: String
        /// The tags assigned to the virtual cluster.
        public let tags: [String: String]?

        public init(clientToken: String = CreateVirtualClusterRequest.idempotencyToken(), containerProvider: ContainerProvider, name: String, tags: [String: String]? = nil) {
            self.clientToken = clientToken
            self.containerProvider = containerProvider
            self.name = name
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 64)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: ".*\\S.*")
            try self.containerProvider.validate(name: "\(name).containerProvider")
            try self.validate(self.name, name: "name", parent: name, max: 64)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "[\\.\\-_/#A-Za-z0-9]+")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: ".*\\S.*")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, min: 0)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, pattern: ".*\\S.*")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken
            case containerProvider
            case name
            case tags
        }
    }

    public struct CreateVirtualClusterResponse: AWSDecodableShape {
        /// This output contains the ARN of virtual cluster.
        public let arn: String?
        /// This output contains the virtual cluster ID.
        public let id: String?
        /// This output contains the name of the virtual cluster.
        public let name: String?

        public init(arn: String? = nil, id: String? = nil, name: String? = nil) {
            self.arn = arn
            self.id = id
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case id
            case name
        }
    }

    public struct DeleteManagedEndpointRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "id", location: .uri(locationName: "endpointId")),
            AWSMemberEncoding(label: "virtualClusterId", location: .uri(locationName: "virtualClusterId"))
        ]

        /// The ID of the managed endpoint.
        public let id: String
        /// The ID of the endpoint's virtual cluster.
        public let virtualClusterId: String

        public init(id: String, virtualClusterId: String) {
            self.id = id
            self.virtualClusterId = virtualClusterId
        }

        public func validate(name: String) throws {
            try self.validate(self.id, name: "id", parent: name, max: 64)
            try self.validate(self.id, name: "id", parent: name, min: 1)
            try self.validate(self.id, name: "id", parent: name, pattern: "[0-9a-z]+")
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, max: 64)
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, min: 1)
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, pattern: "[0-9a-z]+")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteManagedEndpointResponse: AWSDecodableShape {
        /// The output displays the ID of the managed endpoint.
        public let id: String?
        /// The output displays the ID of the endpoint's virtual cluster.
        public let virtualClusterId: String?

        public init(id: String? = nil, virtualClusterId: String? = nil) {
            self.id = id
            self.virtualClusterId = virtualClusterId
        }

        private enum CodingKeys: String, CodingKey {
            case id
            case virtualClusterId
        }
    }

    public struct DeleteVirtualClusterRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "id", location: .uri(locationName: "virtualClusterId"))
        ]

        /// The ID of the virtual cluster that will be deleted.
        public let id: String

        public init(id: String) {
            self.id = id
        }

        public func validate(name: String) throws {
            try self.validate(self.id, name: "id", parent: name, max: 64)
            try self.validate(self.id, name: "id", parent: name, min: 1)
            try self.validate(self.id, name: "id", parent: name, pattern: "[0-9a-z]+")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteVirtualClusterResponse: AWSDecodableShape {
        /// This output contains the ID of the virtual cluster that will be deleted.
        public let id: String?

        public init(id: String? = nil) {
            self.id = id
        }

        private enum CodingKeys: String, CodingKey {
            case id
        }
    }

    public struct DescribeJobRunRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "id", location: .uri(locationName: "jobRunId")),
            AWSMemberEncoding(label: "virtualClusterId", location: .uri(locationName: "virtualClusterId"))
        ]

        /// The ID of the job run request.
        public let id: String
        /// The ID of the virtual cluster for which the job run is submitted.
        public let virtualClusterId: String

        public init(id: String, virtualClusterId: String) {
            self.id = id
            self.virtualClusterId = virtualClusterId
        }

        public func validate(name: String) throws {
            try self.validate(self.id, name: "id", parent: name, max: 64)
            try self.validate(self.id, name: "id", parent: name, min: 1)
            try self.validate(self.id, name: "id", parent: name, pattern: "[0-9a-z]+")
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, max: 64)
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, min: 1)
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, pattern: "[0-9a-z]+")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DescribeJobRunResponse: AWSDecodableShape {
        /// The output displays information about a job run.
        public let jobRun: JobRun?

        public init(jobRun: JobRun? = nil) {
            self.jobRun = jobRun
        }

        private enum CodingKeys: String, CodingKey {
            case jobRun
        }
    }

    public struct DescribeManagedEndpointRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "id", location: .uri(locationName: "endpointId")),
            AWSMemberEncoding(label: "virtualClusterId", location: .uri(locationName: "virtualClusterId"))
        ]

        /// This output displays ID of the managed endpoint.
        public let id: String
        /// The ID of the endpoint's virtual cluster.
        public let virtualClusterId: String

        public init(id: String, virtualClusterId: String) {
            self.id = id
            self.virtualClusterId = virtualClusterId
        }

        public func validate(name: String) throws {
            try self.validate(self.id, name: "id", parent: name, max: 64)
            try self.validate(self.id, name: "id", parent: name, min: 1)
            try self.validate(self.id, name: "id", parent: name, pattern: "[0-9a-z]+")
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, max: 64)
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, min: 1)
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, pattern: "[0-9a-z]+")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DescribeManagedEndpointResponse: AWSDecodableShape {
        /// This output displays information about a managed endpoint.
        public let endpoint: Endpoint?

        public init(endpoint: Endpoint? = nil) {
            self.endpoint = endpoint
        }

        private enum CodingKeys: String, CodingKey {
            case endpoint
        }
    }

    public struct DescribeVirtualClusterRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "id", location: .uri(locationName: "virtualClusterId"))
        ]

        /// The ID of the virtual cluster that will be described.
        public let id: String

        public init(id: String) {
            self.id = id
        }

        public func validate(name: String) throws {
            try self.validate(self.id, name: "id", parent: name, max: 64)
            try self.validate(self.id, name: "id", parent: name, min: 1)
            try self.validate(self.id, name: "id", parent: name, pattern: "[0-9a-z]+")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DescribeVirtualClusterResponse: AWSDecodableShape {
        /// This output displays information about the specified virtual cluster.
        public let virtualCluster: VirtualCluster?

        public init(virtualCluster: VirtualCluster? = nil) {
            self.virtualCluster = virtualCluster
        }

        private enum CodingKeys: String, CodingKey {
            case virtualCluster
        }
    }

    public struct EksInfo: AWSEncodableShape & AWSDecodableShape {
        /// The namespaces of the EKS cluster.
        public let namespace: String?

        public init(namespace: String? = nil) {
            self.namespace = namespace
        }

        public func validate(name: String) throws {
            try self.validate(self.namespace, name: "namespace", parent: name, max: 256)
            try self.validate(self.namespace, name: "namespace", parent: name, min: 1)
            try self.validate(self.namespace, name: "namespace", parent: name, pattern: ".*\\S.*")
        }

        private enum CodingKeys: String, CodingKey {
            case namespace
        }
    }

    public struct Endpoint: AWSDecodableShape {
        /// The ARN of the endpoint.
        public let arn: String?
        /// The certificate ARN of the endpoint.
        public let certificateArn: String?
        /// The configuration settings that are used to override existing configurations for endpoints.
        public let configurationOverrides: ConfigurationOverrides?
        /// The date and time when the endpoint was created.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var createdAt: Date?
        /// The execution role ARN of the endpoint.
        public let executionRoleArn: String?
        /// The ID of the endpoint.
        public let id: String?
        /// The name of the endpoint.
        public let name: String?
        /// The EMR release version to be used for the endpoint.
        public let releaseLabel: String?
        /// The security group configuration of the endpoint.
        public let securityGroup: String?
        /// The server URL of the endpoint.
        public let serverUrl: String?
        /// The state of the endpoint.
        public let state: EndpointState?
        /// The subnet IDs of the endpoint.
        public let subnetIds: [String]?
        /// The tags of the endpoint.
        public let tags: [String: String]?
        /// The type of the endpoint.
        public let type: String?
        /// The ID of the endpoint's virtual cluster.
        public let virtualClusterId: String?

        public init(arn: String? = nil, certificateArn: String? = nil, configurationOverrides: ConfigurationOverrides? = nil, createdAt: Date? = nil, executionRoleArn: String? = nil, id: String? = nil, name: String? = nil, releaseLabel: String? = nil, securityGroup: String? = nil, serverUrl: String? = nil, state: EndpointState? = nil, subnetIds: [String]? = nil, tags: [String: String]? = nil, type: String? = nil, virtualClusterId: String? = nil) {
            self.arn = arn
            self.certificateArn = certificateArn
            self.configurationOverrides = configurationOverrides
            self.createdAt = createdAt
            self.executionRoleArn = executionRoleArn
            self.id = id
            self.name = name
            self.releaseLabel = releaseLabel
            self.securityGroup = securityGroup
            self.serverUrl = serverUrl
            self.state = state
            self.subnetIds = subnetIds
            self.tags = tags
            self.type = type
            self.virtualClusterId = virtualClusterId
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case certificateArn
            case configurationOverrides
            case createdAt
            case executionRoleArn
            case id
            case name
            case releaseLabel
            case securityGroup
            case serverUrl
            case state
            case subnetIds
            case tags
            case type
            case virtualClusterId
        }
    }

    public struct JobDriver: AWSEncodableShape & AWSDecodableShape {
        /// The job driver parameters specified for spark submit.
        public let sparkSubmitJobDriver: SparkSubmitJobDriver?

        public init(sparkSubmitJobDriver: SparkSubmitJobDriver? = nil) {
            self.sparkSubmitJobDriver = sparkSubmitJobDriver
        }

        public func validate(name: String) throws {
            try self.sparkSubmitJobDriver?.validate(name: "\(name).sparkSubmitJobDriver")
        }

        private enum CodingKeys: String, CodingKey {
            case sparkSubmitJobDriver
        }
    }

    public struct JobRun: AWSDecodableShape {
        /// The ARN of job run.
        public let arn: String?
        /// The client token used to start a job run.
        public let clientToken: String?
        /// The configuration settings that are used to override default configuration.
        public let configurationOverrides: ConfigurationOverrides?
        /// The date and time when the job run was created.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var createdAt: Date?
        /// The user who created the job run.
        public let createdBy: String?
        /// The execution role ARN of the job run.
        public let executionRoleArn: String?
        /// The reasons why the job run has failed.
        public let failureReason: FailureReason?
        /// The date and time when the job run has finished.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var finishedAt: Date?
        /// The ID of the job run.
        public let id: String?
        /// Parameters of job driver for the job run.
        public let jobDriver: JobDriver?
        /// The name of the job run.
        public let name: String?
        /// The release version of Amazon EMR.
        public let releaseLabel: String?
        /// The state of the job run.
        public let state: JobRunState?
        /// Additional details of the job run state.
        public let stateDetails: String?
        /// The assigned tags of the job run.
        public let tags: [String: String]?
        /// The ID of the job run's virtual cluster.
        public let virtualClusterId: String?

        public init(arn: String? = nil, clientToken: String? = nil, configurationOverrides: ConfigurationOverrides? = nil, createdAt: Date? = nil, createdBy: String? = nil, executionRoleArn: String? = nil, failureReason: FailureReason? = nil, finishedAt: Date? = nil, id: String? = nil, jobDriver: JobDriver? = nil, name: String? = nil, releaseLabel: String? = nil, state: JobRunState? = nil, stateDetails: String? = nil, tags: [String: String]? = nil, virtualClusterId: String? = nil) {
            self.arn = arn
            self.clientToken = clientToken
            self.configurationOverrides = configurationOverrides
            self.createdAt = createdAt
            self.createdBy = createdBy
            self.executionRoleArn = executionRoleArn
            self.failureReason = failureReason
            self.finishedAt = finishedAt
            self.id = id
            self.jobDriver = jobDriver
            self.name = name
            self.releaseLabel = releaseLabel
            self.state = state
            self.stateDetails = stateDetails
            self.tags = tags
            self.virtualClusterId = virtualClusterId
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case clientToken
            case configurationOverrides
            case createdAt
            case createdBy
            case executionRoleArn
            case failureReason
            case finishedAt
            case id
            case jobDriver
            case name
            case releaseLabel
            case state
            case stateDetails
            case tags
            case virtualClusterId
        }
    }

    public struct ListJobRunsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "_createdAfter", location: .querystring(locationName: "createdAfter")),
            AWSMemberEncoding(label: "_createdBefore", location: .querystring(locationName: "createdBefore")),
            AWSMemberEncoding(label: "maxResults", location: .querystring(locationName: "maxResults")),
            AWSMemberEncoding(label: "name", location: .querystring(locationName: "name")),
            AWSMemberEncoding(label: "nextToken", location: .querystring(locationName: "nextToken")),
            AWSMemberEncoding(label: "states", location: .querystring(locationName: "states")),
            AWSMemberEncoding(label: "virtualClusterId", location: .uri(locationName: "virtualClusterId"))
        ]

        /// The date and time after which the job runs were submitted.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var createdAfter: Date?
        /// The date and time before which the job runs were submitted.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var createdBefore: Date?
        /// The maximum number of job runs that can be listed.
        public let maxResults: Int?
        /// The name of the job run.
        public let name: String?
        /// The token for the next set of job runs to return.
        public let nextToken: String?
        /// The states of the job run.
        public let states: [JobRunState]?
        /// The ID of the virtual cluster for which to list the job run.
        public let virtualClusterId: String

        public init(createdAfter: Date? = nil, createdBefore: Date? = nil, maxResults: Int? = nil, name: String? = nil, nextToken: String? = nil, states: [JobRunState]? = nil, virtualClusterId: String) {
            self.createdAfter = createdAfter
            self.createdBefore = createdBefore
            self.maxResults = maxResults
            self.name = name
            self.nextToken = nextToken
            self.states = states
            self.virtualClusterId = virtualClusterId
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 64)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "[\\.\\-_/#A-Za-z0-9]+")
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: ".*\\S.*")
            try self.validate(self.states, name: "states", parent: name, max: 10)
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, max: 64)
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, min: 1)
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, pattern: "[0-9a-z]+")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListJobRunsResponse: AWSDecodableShape {
        /// This output lists information about the specified job runs.
        public let jobRuns: [JobRun]?
        /// This output displays the token for the next set of job runs.
        public let nextToken: String?

        public init(jobRuns: [JobRun]? = nil, nextToken: String? = nil) {
            self.jobRuns = jobRuns
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case jobRuns
            case nextToken
        }
    }

    public struct ListManagedEndpointsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "_createdAfter", location: .querystring(locationName: "createdAfter")),
            AWSMemberEncoding(label: "_createdBefore", location: .querystring(locationName: "createdBefore")),
            AWSMemberEncoding(label: "maxResults", location: .querystring(locationName: "maxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring(locationName: "nextToken")),
            AWSMemberEncoding(label: "states", location: .querystring(locationName: "states")),
            AWSMemberEncoding(label: "types", location: .querystring(locationName: "types")),
            AWSMemberEncoding(label: "virtualClusterId", location: .uri(locationName: "virtualClusterId"))
        ]

        ///  The date and time after which the endpoints are created.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var createdAfter: Date?
        /// The date and time before which the endpoints are created.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var createdBefore: Date?
        /// The maximum number of managed endpoints that can be listed.
        public let maxResults: Int?
        ///  The token for the next set of managed endpoints to return.
        public let nextToken: String?
        /// The states of the managed endpoints.
        public let states: [EndpointState]?
        /// The types of the managed endpoints.
        public let types: [String]?
        /// The ID of the virtual cluster.
        public let virtualClusterId: String

        public init(createdAfter: Date? = nil, createdBefore: Date? = nil, maxResults: Int? = nil, nextToken: String? = nil, states: [EndpointState]? = nil, types: [String]? = nil, virtualClusterId: String) {
            self.createdAfter = createdAfter
            self.createdBefore = createdBefore
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.states = states
            self.types = types
            self.virtualClusterId = virtualClusterId
        }

        public func validate(name: String) throws {
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: ".*\\S.*")
            try self.validate(self.states, name: "states", parent: name, max: 10)
            try self.types?.forEach {
                try validate($0, name: "types[]", parent: name, max: 64)
                try validate($0, name: "types[]", parent: name, min: 1)
                try validate($0, name: "types[]", parent: name, pattern: ".*\\S.*")
            }
            try self.validate(self.types, name: "types", parent: name, max: 10)
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, max: 64)
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, min: 1)
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, pattern: "[0-9a-z]+")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListManagedEndpointsResponse: AWSDecodableShape {
        /// The managed endpoints to be listed.
        public let endpoints: [Endpoint]?
        ///  The token for the next set of endpoints to return.
        public let nextToken: String?

        public init(endpoints: [Endpoint]? = nil, nextToken: String? = nil) {
            self.endpoints = endpoints
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case endpoints
            case nextToken
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri(locationName: "resourceArn"))
        ]

        /// The ARN of tagged resources.
        public let resourceArn: String

        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 500)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 60)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:(aws[a-zA-Z0-9-]*):emr-containers:.+:(\\d{12}):/virtualclusters/.+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// The tags assigned to resources.
        public let tags: [String: String]?

        public init(tags: [String: String]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags
        }
    }

    public struct ListVirtualClustersRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "containerProviderId", location: .querystring(locationName: "containerProviderId")),
            AWSMemberEncoding(label: "containerProviderType", location: .querystring(locationName: "containerProviderType")),
            AWSMemberEncoding(label: "_createdAfter", location: .querystring(locationName: "createdAfter")),
            AWSMemberEncoding(label: "_createdBefore", location: .querystring(locationName: "createdBefore")),
            AWSMemberEncoding(label: "maxResults", location: .querystring(locationName: "maxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring(locationName: "nextToken")),
            AWSMemberEncoding(label: "states", location: .querystring(locationName: "states"))
        ]

        /// The container provider ID of the virtual cluster.
        public let containerProviderId: String?
        /// The container provider type of the virtual cluster. EKS is the only supported type as of now.
        public let containerProviderType: ContainerProviderType?
        /// The date and time after which the virtual clusters are created.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var createdAfter: Date?
        /// The date and time before which the virtual clusters are created.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var createdBefore: Date?
        /// The maximum number of virtual clusters that can be listed.
        public let maxResults: Int?
        /// The token for the next set of virtual clusters to return.
        public let nextToken: String?
        /// The states of the requested virtual clusters.
        public let states: [VirtualClusterState]?

        public init(containerProviderId: String? = nil, containerProviderType: ContainerProviderType? = nil, createdAfter: Date? = nil, createdBefore: Date? = nil, maxResults: Int? = nil, nextToken: String? = nil, states: [VirtualClusterState]? = nil) {
            self.containerProviderId = containerProviderId
            self.containerProviderType = containerProviderType
            self.createdAfter = createdAfter
            self.createdBefore = createdBefore
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.states = states
        }

        public func validate(name: String) throws {
            try self.validate(self.containerProviderId, name: "containerProviderId", parent: name, max: 1024)
            try self.validate(self.containerProviderId, name: "containerProviderId", parent: name, min: 1)
            try self.validate(self.containerProviderId, name: "containerProviderId", parent: name, pattern: ".*\\S.*")
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: ".*\\S.*")
            try self.validate(self.states, name: "states", parent: name, max: 10)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListVirtualClustersResponse: AWSDecodableShape {
        /// This output displays the token for the next set of virtual clusters.
        public let nextToken: String?
        /// This output lists the specified virtual clusters.
        public let virtualClusters: [VirtualCluster]?

        public init(nextToken: String? = nil, virtualClusters: [VirtualCluster]? = nil) {
            self.nextToken = nextToken
            self.virtualClusters = virtualClusters
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken
            case virtualClusters
        }
    }

    public struct MonitoringConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// Monitoring configurations for CloudWatch.
        public let cloudWatchMonitoringConfiguration: CloudWatchMonitoringConfiguration?
        /// Monitoring configurations for the persistent application UI.
        public let persistentAppUI: PersistentAppUI?
        /// Amazon S3 configuration for monitoring log publishing.
        public let s3MonitoringConfiguration: S3MonitoringConfiguration?

        public init(cloudWatchMonitoringConfiguration: CloudWatchMonitoringConfiguration? = nil, persistentAppUI: PersistentAppUI? = nil, s3MonitoringConfiguration: S3MonitoringConfiguration? = nil) {
            self.cloudWatchMonitoringConfiguration = cloudWatchMonitoringConfiguration
            self.persistentAppUI = persistentAppUI
            self.s3MonitoringConfiguration = s3MonitoringConfiguration
        }

        public func validate(name: String) throws {
            try self.cloudWatchMonitoringConfiguration?.validate(name: "\(name).cloudWatchMonitoringConfiguration")
            try self.s3MonitoringConfiguration?.validate(name: "\(name).s3MonitoringConfiguration")
        }

        private enum CodingKeys: String, CodingKey {
            case cloudWatchMonitoringConfiguration
            case persistentAppUI
            case s3MonitoringConfiguration
        }
    }

    public struct S3MonitoringConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// Amazon S3 destination URI for log publishing.
        public let logUri: String

        public init(logUri: String) {
            self.logUri = logUri
        }

        public func validate(name: String) throws {
            try self.validate(self.logUri, name: "logUri", parent: name, max: 10280)
            try self.validate(self.logUri, name: "logUri", parent: name, min: 1)
            try self.validate(self.logUri, name: "logUri", parent: name, pattern: "[\\u0020-\\uD7FF\\uE000-\\uFFFD\\uD800\\uDBFF-\\uDC00\\uDFFF\\r\\n\\t]*")
        }

        private enum CodingKeys: String, CodingKey {
            case logUri
        }
    }

    public struct SparkSubmitJobDriver: AWSEncodableShape & AWSDecodableShape {
        /// The entry point of job application.
        public let entryPoint: String
        /// The arguments for job application.
        public let entryPointArguments: [String]?
        /// The Spark submit parameters that are used for job runs.
        public let sparkSubmitParameters: String?

        public init(entryPoint: String, entryPointArguments: [String]? = nil, sparkSubmitParameters: String? = nil) {
            self.entryPoint = entryPoint
            self.entryPointArguments = entryPointArguments
            self.sparkSubmitParameters = sparkSubmitParameters
        }

        public func validate(name: String) throws {
            try self.validate(self.entryPoint, name: "entryPoint", parent: name, max: 256)
            try self.validate(self.entryPoint, name: "entryPoint", parent: name, min: 1)
            try self.validate(self.entryPoint, name: "entryPoint", parent: name, pattern: "(?!\\s*$)(^[^';|\\u0026\\u003C\\u003E*?`$(){}\\[\\]!#\\\\]*$)")
            try self.entryPointArguments?.forEach {
                try validate($0, name: "entryPointArguments[]", parent: name, max: 10280)
                try validate($0, name: "entryPointArguments[]", parent: name, min: 1)
                try validate($0, name: "entryPointArguments[]", parent: name, pattern: "(?!\\s*$)(^[^';|\\u0026\\u003C\\u003E*?`$(){}\\[\\]!#\\\\]*$)")
            }
            try self.validate(self.sparkSubmitParameters, name: "sparkSubmitParameters", parent: name, max: 1024)
            try self.validate(self.sparkSubmitParameters, name: "sparkSubmitParameters", parent: name, min: 1)
            try self.validate(self.sparkSubmitParameters, name: "sparkSubmitParameters", parent: name, pattern: "(?!\\s*$)(^[^';|\\u0026\\u003C\\u003E*?`$(){}\\[\\]!#\\\\]*$)")
        }

        private enum CodingKeys: String, CodingKey {
            case entryPoint
            case entryPointArguments
            case sparkSubmitParameters
        }
    }

    public struct StartJobRunRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "virtualClusterId", location: .uri(locationName: "virtualClusterId"))
        ]

        /// The client idempotency token of the job run request.
        public let clientToken: String
        /// The configuration overrides for the job run.
        public let configurationOverrides: ConfigurationOverrides?
        /// The execution role ARN for the job run.
        public let executionRoleArn: String
        /// The job driver for the job run.
        public let jobDriver: JobDriver
        /// The name of the job run.
        public let name: String?
        /// The Amazon EMR release version to use for the job run.
        public let releaseLabel: String
        /// The tags assigned to job runs.
        public let tags: [String: String]?
        /// The virtual cluster ID for which the job run request is submitted.
        public let virtualClusterId: String

        public init(clientToken: String = StartJobRunRequest.idempotencyToken(), configurationOverrides: ConfigurationOverrides? = nil, executionRoleArn: String, jobDriver: JobDriver, name: String? = nil, releaseLabel: String, tags: [String: String]? = nil, virtualClusterId: String) {
            self.clientToken = clientToken
            self.configurationOverrides = configurationOverrides
            self.executionRoleArn = executionRoleArn
            self.jobDriver = jobDriver
            self.name = name
            self.releaseLabel = releaseLabel
            self.tags = tags
            self.virtualClusterId = virtualClusterId
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 64)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: ".*\\S.*")
            try self.configurationOverrides?.validate(name: "\(name).configurationOverrides")
            try self.validate(self.executionRoleArn, name: "executionRoleArn", parent: name, max: 2048)
            try self.validate(self.executionRoleArn, name: "executionRoleArn", parent: name, min: 20)
            try self.validate(self.executionRoleArn, name: "executionRoleArn", parent: name, pattern: "^arn:(aws[a-zA-Z0-9-]*):iam::(\\d{12})?:(role((\\u002F)|(\\u002F[\\u0021-\\u007F]+\\u002F))[\\w+=,.@-]+)$")
            try self.jobDriver.validate(name: "\(name).jobDriver")
            try self.validate(self.name, name: "name", parent: name, max: 64)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "[\\.\\-_/#A-Za-z0-9]+")
            try self.validate(self.releaseLabel, name: "releaseLabel", parent: name, max: 64)
            try self.validate(self.releaseLabel, name: "releaseLabel", parent: name, min: 1)
            try self.validate(self.releaseLabel, name: "releaseLabel", parent: name, pattern: "[\\.\\-_/A-Za-z0-9]+")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: ".*\\S.*")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, min: 0)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, pattern: ".*\\S.*")
            }
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, max: 64)
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, min: 1)
            try self.validate(self.virtualClusterId, name: "virtualClusterId", parent: name, pattern: "[0-9a-z]+")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken
            case configurationOverrides
            case executionRoleArn
            case jobDriver
            case name
            case releaseLabel
            case tags
        }
    }

    public struct StartJobRunResponse: AWSDecodableShape {
        /// This output lists the ARN of job run.
        public let arn: String?
        /// This output displays the started job run ID.
        public let id: String?
        /// This output displays the name of the started job run.
        public let name: String?
        /// This output displays the virtual cluster ID for which the job run was submitted.
        public let virtualClusterId: String?

        public init(arn: String? = nil, id: String? = nil, name: String? = nil, virtualClusterId: String? = nil) {
            self.arn = arn
            self.id = id
            self.name = name
            self.virtualClusterId = virtualClusterId
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case id
            case name
            case virtualClusterId
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri(locationName: "resourceArn"))
        ]

        /// The ARN of resources.
        public let resourceArn: String
        /// The tags assigned to resources.
        public let tags: [String: String]

        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 500)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 60)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:(aws[a-zA-Z0-9-]*):emr-containers:.+:(\\d{12}):/virtualclusters/.+$")
            try self.tags.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: ".*\\S.*")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, min: 0)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, pattern: ".*\\S.*")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case tags
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri(locationName: "resourceArn")),
            AWSMemberEncoding(label: "tagKeys", location: .querystring(locationName: "tagKeys"))
        ]

        /// The ARN of resources.
        public let resourceArn: String
        /// The tag keys of the resources.
        public let tagKeys: [String]

        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 500)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 60)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:(aws[a-zA-Z0-9-]*):emr-containers:.+:(\\d{12}):/virtualclusters/.+$")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
                try validate($0, name: "tagKeys[]", parent: name, pattern: ".*\\S.*")
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 50)
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, min: 0)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct VirtualCluster: AWSDecodableShape {
        /// The ARN of the virtual cluster.
        public let arn: String?
        /// The container provider of the virtual cluster.
        public let containerProvider: ContainerProvider?
        /// The date and time when the virtual cluster is created.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var createdAt: Date?
        /// The ID of the virtual cluster.
        public let id: String?
        /// The name of the virtual cluster.
        public let name: String?
        /// The state of the virtual cluster.
        public let state: VirtualClusterState?
        /// The assigned tags of the virtual cluster.
        public let tags: [String: String]?

        public init(arn: String? = nil, containerProvider: ContainerProvider? = nil, createdAt: Date? = nil, id: String? = nil, name: String? = nil, state: VirtualClusterState? = nil, tags: [String: String]? = nil) {
            self.arn = arn
            self.containerProvider = containerProvider
            self.createdAt = createdAt
            self.id = id
            self.name = name
            self.state = state
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case containerProvider
            case createdAt
            case id
            case name
            case state
            case tags
        }
    }
}
